﻿using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;

public static class JwtExtensions
{
    public static IServiceCollection AddJWTAuthorization(this IServiceCollection Services, IConfiguration configuration)
    {
        var section = configuration.GetSection("TokenOptions"); // 获取TokenOptions配置
        var tokenOptions = new TokenOptions();
        section.Bind(tokenOptions);

        Services.Configure<TokenOptions>(section); // 注入IOptions需要这个
        Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = true,//是否在令牌期间验证签发者
                    ValidateAudience = true,//是否验证接收者
                    ValidateLifetime = true,//是否验证失效时间
                    ValidateIssuerSigningKey = true,//是否验证签名
                    ValidAudience = tokenOptions.Audience,//接收者
                    ValidIssuer = tokenOptions.Issuer,//签发者，签发的Token的人
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(tokenOptions.SecretKey))
                };
                options.Events = new JwtBearerEvents
                {
                    //权限验证失败后执行
                    OnChallenge = context =>
                    {
                        //终止默认的返回结果(必须有)
                        context.HandleResponse();
                        var result = JsonConvert.SerializeObject(new { Code = 402, Message = "Jwt权限认证失败" });
                        context.Response.ContentType = "application/json";
                        //验证失败返回401
                        context.Response.StatusCode = StatusCodes.Status401Unauthorized;
                        context.Response.WriteAsync(result);
                        return Task.FromResult(0);
                    }
                };
            });
        return Services;
    }
}